﻿using Layer;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Xml.Linq;


namespace PremisPublisher.Common
{
    /// <summary>
    /// 分析项目文件(*.csproj)，取得ItemGroup->Content-Include里面的值，上传到服务器存储，
    /// 执行存储过程生成xml配置文件并下载，然后根据配置文件进行发布
    /// </summary>
    public class ProjectsAnalyzer
    {
        public static readonly ProjectsAnalyzer instance = new ProjectsAnalyzer();

        public static ProjectsAnalyzer GetInstance()
        { return instance; }

        List<string> _solutionProjects = null;

        private ProjectsAnalyzer()
        {
            ServiceCaller.TcpServiceDispatcher<IPRMIS_U_Contract.IPremisPublish>("0099", svc =>
            {
                _solutionProjects = svc.PullPublishProjects();
            });
        }

        /// <summary>
        /// 获取项目包含文件
        /// </summary>
        /// <param name="project_file">.csproj</param>
        /// <returns></returns>
        IEnumerable<string> _get_project_files(string project_file)
        {
            IEnumerable<string> result = new List<string>();

            var project_name = System.IO.Path.GetFileNameWithoutExtension(project_file).ToLower();

            ServiceCaller.TcpServiceDispatcher<IPRMIS_U_Contract.IPremisPublish>("0099", svc =>
            {
                System.Data.DataTable dt = svc.PullExceptDirectorys();

                var r = from DataRow dataRow in dt.Rows
                        where dataRow.Field<string>("publish_source").ToLower() == project_name
                        select dataRow.Field<string>("publish_item").ToLower();

                result = from n in XDocument.Load(project_file).Element("{http://schemas.microsoft.com/developer/msbuild/2003}Project").Elements("{http://schemas.microsoft.com/developer/msbuild/2003}ItemGroup").Elements("{http://schemas.microsoft.com/developer/msbuild/2003}Content")
                         where !r.Contains(n.Attribute("Include").Value.Split('\\')[0].ToLower())
                         select n.Attribute("Include").Value;
            });

            return result;
        }


        string _get_source_root_path()
        {
            return System.IO.Path.GetFullPath( System.Configuration.ConfigurationManager.AppSettings.Get("SourcePath"));
        }

        /// <summary>
        /// 获取所有csproj文件
        /// </summary>
        /// <returns></returns>
        public List<string> get_all_project_csproj()
        {
            var root_path =  System.IO.Path.GetDirectoryName( _get_source_root_path());

            var c = System.IO.Directory.GetFiles(root_path, "*.csproj", System.IO.SearchOption.AllDirectories);
            var sp = from n in _solutionProjects select System.IO.Path.Combine(root_path, n).ToLower();
            var x = from n in c
                    where sp.Count(s => s.Equals(System.IO.Path.GetDirectoryName(n).ToLower())) == 1
                    select n;

            return x.ToList();
        }

        /// <summary>
        /// 向wcf服务提交数据
        /// </summary>
        /// <param name="commit_callback">callback</param>
        public void CommitProjectFiles(Action<string, bool> commit_callback)
        {
            ServiceCaller.TcpServiceDispatcher<IPRMIS_U_Contract.IPremisPublish>("0099", svc =>
            {
                foreach (var p in get_all_project_csproj())
                {
                    var result = svc.ReceivePublishProjectFiles(
                        System.IO.Path.GetFileNameWithoutExtension(p),
                        _get_project_files(p).ToArray());
                    commit_callback(p, result);
                }
            });
        }


        /// <summary>
        /// 从服务器获取 xml 配置文件
        /// </summary>
        /// <param name="get_callback">执行回调前必须检查result的值是否为空，以及xml文件合法性（Common.ValidateXmlFile.ValidateXml）</param>
        public void GetPublishXmlContent(Action<string> get_callback)
        {
            string result = string.Empty;

            Dictionary<string, string> proc_params = new Dictionary<string, string>();
            proc_params.Add("@V_ENCODING", System.Configuration.ConfigurationManager.AppSettings.Get("ENCODING"));
            proc_params.Add("@V_VERSION_ID", System.Configuration.ConfigurationManager.AppSettings.Get("VERSION"));
            proc_params.Add("@V_PUBLIC_KEY", "5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=");
            proc_params.Add("@V_EXPONENT_KEY", "AQAB");
            proc_params.Add("@V_WEB_CONFIG", string.Join(",", _solutionProjects));
            proc_params.Add("@V_SOURCE_PATH", System.Configuration.ConfigurationManager.AppSettings.Get("SourcePath"));
            proc_params.Add("@V_BUILDOUTPUT_PATH", System.Configuration.ConfigurationManager.AppSettings.Get("msbuild_output_path"));
            proc_params.Add("@V_JSHOST_PATH", System.Configuration.ConfigurationManager.AppSettings.Get("JSHOST_PATH"));

            ServiceCaller.TcpServiceDispatcher<IPRMIS_U_Contract.IPremisPublish>("0099", svc =>
            {
                result = svc.PullPublishXmlContent(proc_params);
            });


            get_callback(result);

        }
    }
}
